import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  ReadResourceRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { ComponentRegistry } from '../components/ComponentRegistry.js';
import { CodeGenerator } from '../components/CodeGenerator.js';
import { TemplateEngine } from '../templates/TemplateEngine.js';
import { DocumentSearcher } from '../docs/DocumentSearcher.js';
import type { 
  GenerateCodeParams, 
  SearchComponentsParams, 
  GetDocumentationParams,
  ComponentInfo,
  TemplateInfo
} from '../types/index.js';

export class MCPAntDServer {
  private server: Server;
  private componentRegistry: ComponentRegistry;
  private codeGenerator: CodeGenerator;
  private templateEngine: TemplateEngine;
  private documentSearcher: DocumentSearcher;

  constructor() {
    this.server = new Server(
      {
        name: 'mcp-server-antd',
        version: '1.0.0',
      },
      {
        capabilities: {
          resources: {},
          tools: {},
        },
      }
    );

    this.componentRegistry = new ComponentRegistry();
    this.codeGenerator = new CodeGenerator();
    this.templateEngine = new TemplateEngine();
    this.documentSearcher = new DocumentSearcher();

    this.setupHandlers();
  }

  private setupHandlers(): void {
    // List available tools
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          {
            name: 'generate_antd_code',
            description: '生成 Ant Design 组件代码',
            inputSchema: {
              type: 'object',
              properties: {
                component: {
                  type: 'string',
                  description: '组件名称 (如: Button, Table, Form)',
                },
                props: {
                  type: 'object',
                  description: '组件属性',
                },
                template: {
                  type: 'string',
                  description: '模板类型',
                },
                framework: {
                  type: 'string',
                  enum: ['react', 'vue', 'angular'],
                  description: '前端框架',
                  default: 'react',
                },
                includeImports: {
                  type: 'boolean',
                  description: '是否包含导入语句',
                  default: true,
                },
                includeStyles: {
                  type: 'boolean',
                  description: '是否包含样式',
                  default: false,
                },
              },
              required: ['component'],
            },
          },
          {
            name: 'search_antd_components',
            description: '搜索 Ant Design 组件',
            inputSchema: {
              type: 'object',
              properties: {
                query: {
                  type: 'string',
                  description: '搜索查询',
                },
                category: {
                  type: 'string',
                  description: '组件分类',
                },
                limit: {
                  type: 'number',
                  description: '结果数量限制',
                  default: 10,
                },
              },
              required: ['query'],
            },
          },
          {
            name: 'get_antd_documentation',
            description: '获取 Ant Design 组件文档',
            inputSchema: {
              type: 'object',
              properties: {
                component: {
                  type: 'string',
                  description: '组件名称',
                },
                version: {
                  type: 'string',
                  description: 'Ant Design 版本',
                },
                language: {
                  type: 'string',
                  enum: ['zh', 'en'],
                  description: '文档语言',
                  default: 'zh',
                },
              },
              required: ['component'],
            },
          },
          {
            name: 'list_antd_templates',
            description: '列出可用的 Ant Design 模板',
            inputSchema: {
              type: 'object',
              properties: {
                category: {
                  type: 'string',
                  description: '模板分类',
                },
                framework: {
                  type: 'string',
                  enum: ['react', 'vue', 'angular'],
                  description: '前端框架',
                },
              },
            },
          },
        ],
      };
    });

    // Handle tool calls
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;

      switch (name) {
        case 'generate_antd_code':
          return await this.handleGenerateCode(this.validateGenerateCodeParams(args));
        
        case 'search_antd_components':
          return await this.handleSearchComponents(this.validateSearchComponentsParams(args));
        
        case 'get_antd_documentation':
          return await this.handleGetDocumentation(this.validateGetDocumentationParams(args));
        
        case 'list_antd_templates':
          return await this.handleListTemplates(args || {});
        
        default:
          throw new Error(`Unknown tool: ${name}`);
      }
    });

    // List available resources
    this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
      const components = await this.componentRegistry.getAllComponents();
      const templates = await this.templateEngine.getAllTemplates();

      return {
        resources: [
          ...components.map((comp: ComponentInfo) => ({
            uri: `antd://component/${comp.name}`,
            name: `Ant Design ${comp.name}`,
            description: comp.description,
            mimeType: 'application/json',
          })),
          ...templates.map((template: TemplateInfo) => ({
            uri: `antd://template/${template.name}`,
            name: `Template: ${template.name}`,
            description: template.description,
            mimeType: 'text/plain',
          })),
        ],
      };
    });

    // Handle resource reads
    this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
      const { uri } = request.params;
      
      if (uri.startsWith('antd://component/')) {
        const componentName = uri.replace('antd://component/', '');
        const component = await this.componentRegistry.getComponent(componentName);
        
        if (!component) {
          throw new Error(`Component not found: ${componentName}`);
        }
        
        return {
          contents: [
            {
              uri,
              mimeType: 'application/json',
              text: JSON.stringify(component, null, 2),
            },
          ],
        };
      }
      
      if (uri.startsWith('antd://template/')) {
        const templateName = uri.replace('antd://template/', '');
        const template = await this.templateEngine.getTemplate(templateName);
        
        if (!template) {
          throw new Error(`Template not found: ${templateName}`);
        }
        
        return {
          contents: [
            {
              uri,
              mimeType: 'text/plain',
              text: template.template,
            },
          ],
        };
      }
      
      throw new Error(`Unknown resource: ${uri}`);
    });
  }

  private async handleGenerateCode(params: GenerateCodeParams) {
    try {
      const code = await this.codeGenerator.generateCode(params);
      return {
        content: [
          {
            type: 'text',
            text: `生成的 ${params.component} 组件代码:\n\n\`\`\`${params.framework || 'react'}\n${code}\n\`\`\``,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `代码生成失败: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
        isError: true,
      };
    }
  }

  private async handleSearchComponents(params: SearchComponentsParams) {
    try {
      const components = await this.componentRegistry.searchComponents(
        params.query,
        params.category,
        params.limit
      );
      
      const result = components.map((comp: ComponentInfo) => 
        `**${comp.name}** (${comp.category})\n${comp.description}\n`
      ).join('\n');
      
      return {
        content: [
          {
            type: 'text',
            text: `找到 ${components.length} 个组件:\n\n${result}`,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `搜索失败: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
        isError: true,
      };
    }
  }

  private async handleGetDocumentation(params: GetDocumentationParams) {
    try {
      const docs = await this.documentSearcher.getComponentDocs(
        params.component,
        params.version,
        params.language
      );
      
      return {
        content: [
          {
            type: 'text',
            text: `${params.component} 组件文档:\n\n${docs}`,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `获取文档失败: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
        isError: true,
      };
    }
  }

  private async handleListTemplates(params: any) {
    try {
      const templates = await this.templateEngine.getTemplatesByCategory(
        params.category,
        params.framework
      );
      
      const result = templates.map((template: TemplateInfo) => 
        `**${template.name}**\n${template.description}\n框架: ${template.framework}\n`
      ).join('\n');
      
      return {
        content: [
          {
            type: 'text',
            text: `可用模板:\n\n${result}`,
          },
        ],
      };
    } catch (error) {
      return {
        content: [
          {
            type: 'text',
            text: `获取模板失败: ${error instanceof Error ? error.message : String(error)}`,
          },
        ],
        isError: true,
      };
    }
  }

  async run(): Promise<void> {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    console.error('MCP Ant Design Server running on stdio');
  }

  private validateGenerateCodeParams(args: unknown): GenerateCodeParams {
    if (!args || typeof args !== 'object') {
      throw new Error('Invalid arguments: expected object');
    }
    
    const params = args as Record<string, unknown>;
    
    if (!params.component || typeof params.component !== 'string') {
      throw new Error('Missing required parameter: component');
    }
    
    return {
      component: params.component,
      props: (params.props as Record<string, any>) || {},
      template: typeof params.template === 'string' ? params.template : undefined,
      framework: ['react', 'vue', 'angular'].includes(params.framework as string) 
        ? (params.framework as 'react' | 'vue' | 'angular') 
        : 'react',
      includeImports: typeof params.includeImports === 'boolean' ? params.includeImports : true,
      includeStyles: typeof params.includeStyles === 'boolean' ? params.includeStyles : false,
    };
  }

  private validateSearchComponentsParams(args: unknown): SearchComponentsParams {
    if (!args || typeof args !== 'object') {
      throw new Error('Invalid arguments: expected object');
    }
    
    const params = args as Record<string, unknown>;
    
    if (!params.query || typeof params.query !== 'string') {
      throw new Error('Missing required parameter: query');
    }
    
    return {
      query: params.query,
      category: typeof params.category === 'string' ? params.category : undefined,
      limit: typeof params.limit === 'number' ? params.limit : 10,
    };
  }

  private validateGetDocumentationParams(args: unknown): GetDocumentationParams {
    if (!args || typeof args !== 'object') {
      throw new Error('Invalid arguments: expected object');
    }
    
    const params = args as Record<string, unknown>;
    
    if (!params.component || typeof params.component !== 'string') {
      throw new Error('Missing required parameter: component');
    }
    
    return {
      component: params.component,
      version: typeof params.version === 'string' ? params.version : undefined,
      language: ['zh', 'en'].includes(params.language as string) 
        ? (params.language as 'zh' | 'en') 
        : 'zh',
    };
  }
}